/*
 * @Author:  WRay
 * @Date: 2021-11-09 15:05:13
 * @LastEditors:  WRay
 * @LastEditTime: 2021-11-09 17:33:58
 * @Description:
 * ===============+++++++++======================
 */
#include <stdio.h>
#include <iostream>
#include <opencv4/opencv2/opencv.hpp>
#include <vector>

#include "R_CameraD.h"
#include "R_GlobalMethod.h"

using namespace std;

//单位像素宽/高 （cm/pixel）
#define UNIT_PIXEL_W 0.0008234375
#define UNIT_PIXEL_H 0.000825

R_CameraD::R_CameraD()
{
  printf("%s\n", __STR_FUNCTION__.c_str());

  cv::Mat t_frame;
  cv::VideoCapture t_capture(4);
  const double t_f = 0.35;
  const double t_w = 8.5;
  const double t_h = 5.6;

  if (!t_capture.isOpened())
  {
    printf("The camera is not opened.\n");
    return;
  }

  for (;;)
  {
    t_capture >> t_frame;
    if (t_frame.empty())
    {
      printf("The frame is empty.\n");
      break;
    }
    cv::medianBlur(t_frame, t_frame, 3);
    cv::Mat t_grayImage;
    cv::cvtColor(t_frame, t_grayImage, cv::COLOR_BGR2GRAY);

    // otus 可以换为动态阈值
    cv::threshold(t_grayImage, t_grayImage, NULL, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

    vector<vector<cv::Point>> t_contours;
    vector<cv::Point> t_maxAreaContour;

    cv::findContours(t_grayImage, t_contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_NONE);

    //提取面积最大轮廓
    double t_maxArea = 0;
    for (size_t i = 0; i < t_contours.size(); i++)
    {
      double area = fabs(cv::contourArea(t_contours[i]));
      if (area > t_maxArea)
      {
        t_maxArea = area;
        t_maxAreaContour = t_contours[i];
      }
    }

    //轮廓外正矩形
    cv::Rect t_rect = cv::boundingRect(t_maxAreaContour);
    cv::rectangle(t_frame, cv::Point(t_rect.x, t_rect.y), cv::Point(t_rect.x + t_rect.width, t_rect.y + t_rect.height),
                  cv::Scalar(255, 0, 0), 2, 8);

    //计算成像宽/高
    double t_width = t_rect.width + UNIT_PIXEL_W;
    double t_height = t_rect.height + UNIT_PIXEL_H;
    //风别以宽高为标准计算距离
    double t_distanceW = t_w * t_f / t_width;
    double t_distanceH = t_h * t_f / t_height;

    char t_disW[50], t_disH[50];
    sprintf(t_disW, "DistanceW: %.2f cm", t_distanceW);
    sprintf(t_disH, "DistanceH : %.2f cm", t_distanceH);
    cv::putText(t_frame, t_disW, cv::Point(5, 20), cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(0, 255, 0), 1, 8);
    cv::putText(t_frame, t_disH, cv::Point(5, 40), cv::FONT_HERSHEY_COMPLEX_SMALL, 1, cv::Scalar(0, 255, 0), 1, 8);
    cv::imshow("Frame ", t_frame);
    cv::imshow("Gray ", t_grayImage);
    if ((cv::waitKey(10) & 0XFF) == 27)
      break;
  }
  cv::destroyAllWindows();
  t_capture.release();
}